"""
插件基础类

定义插件的基础接口和元数据结构。
"""

import asyncio
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Set
from dataclasses import dataclass, field
from enum import Enum
from .context import PluginContext
import uuid

# 前向声明，避免循环导入
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from ..ast.base import Ast, AstContext


class PluginState(Enum):
    """插件状态枚举"""
    
    UNLOADED = "unloaded"        # 未加载
    LOADED = "loaded"            # 已加载
    INITIALIZED = "initialized"  # 已初始化
    ACTIVE = "active"            # 活跃状态
    INACTIVE = "inactive"        # 非活跃状态
    ERROR = "error"              # 错误状态
    DESTROYED = "destroyed"      # 已销毁


@dataclass
class PluginMetadata:
    """插件元数据"""
    
    # 基本信息
    name: str
    version: str
    description: str = ""
    author: str = ""
    email: str = ""
    website: str = ""
    license: str = ""
    
    # 依赖信息
    dependencies: List[str] = field(default_factory=list)
    optional_dependencies: List[str] = field(default_factory=list)
    conflicts: List[str] = field(default_factory=list)
    
    # 版本要求
    min_mixvideo_version: str = "0.1.0"
    max_mixvideo_version: str = ""
    python_version: str = ">=3.9"
    
    # 插件分类
    category: str = "general"
    tags: List[str] = field(default_factory=list)
    
    # 配置信息
    config_schema: Dict[str, Any] = field(default_factory=dict)
    default_config: Dict[str, Any] = field(default_factory=dict)
    
    # 权限要求
    permissions: List[str] = field(default_factory=list)
    
    # 其他元数据
    entry_point: str = ""
    plugin_class: str = ""
    priority: int = 100  # 优先级，数字越小优先级越高
    enabled: bool = True
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "name": self.name,
            "version": self.version,
            "description": self.description,
            "author": self.author,
            "email": self.email,
            "website": self.website,
            "license": self.license,
            "dependencies": self.dependencies,
            "optional_dependencies": self.optional_dependencies,
            "conflicts": self.conflicts,
            "min_mixvideo_version": self.min_mixvideo_version,
            "max_mixvideo_version": self.max_mixvideo_version,
            "python_version": self.python_version,
            "category": self.category,
            "tags": self.tags,
            "config_schema": self.config_schema,
            "default_config": self.default_config,
            "permissions": self.permissions,
            "entry_point": self.entry_point,
            "plugin_class": self.plugin_class,
            "priority": self.priority,
            "enabled": self.enabled,
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'PluginMetadata':
        """从字典创建"""
        return cls(**data)


class Plugin(ABC):
    """
    插件抽象基类
    
    所有插件都必须继承此类并实现相应的方法。
    """
    
    def __init__(self):
        self.plugin_id = str(uuid.uuid4())
        self.state = PluginState.UNLOADED
        self.metadata: Optional[PluginMetadata] = None
        self.config: Dict[str, Any] = {}
        self.context: Optional['PluginContext'] = None
        self.logger = None
        
        # 生命周期回调
        self._on_load_callbacks: List[callable] = []
        self._on_unload_callbacks: List[callable] = []
        self._on_error_callbacks: List[callable] = []
    
    @property
    @abstractmethod
    def name(self) -> str:
        """插件名称"""
        pass
    
    @property
    @abstractmethod
    def version(self) -> str:
        """插件版本"""
        pass
    
    @property
    def description(self) -> str:
        """插件描述"""
        return ""
    
    @property
    def author(self) -> str:
        """插件作者"""
        return ""
    
    @property
    def dependencies(self) -> List[str]:
        """插件依赖"""
        return []
    
    # ========================================================================
    # 生命周期方法
    # ========================================================================
    
    async def on_init(self, ctx: Any) -> None:
        """
        插件初始化
        
        在插件加载后调用，用于初始化插件资源。
        
        Args:
            ctx: 插件上下文
        """
        pass
    
    def on_compiler(self, ast: 'Ast', ctx: Any) -> Any:
        """
        编译时处理
        
        在工作流编译时调用，可以修改AST。
        
        Args:
            ast: AST节点
            ctx: 编译上下文
        
        Returns:
            处理后的AST或上下文
        """
        return ast
    
    def on_execute(self, ast: 'Ast', ctx: Any) -> Any:
        """
        执行时处理
        
        在工作流执行时调用，处理具体业务逻辑。
        
        Args:
            ast: AST节点
            ctx: 执行上下文
        
        Returns:
            处理结果
        """
        return ctx
    
    async def on_destroy(self) -> None:
        """
        插件销毁
        
        在插件卸载前调用，用于清理资源。
        """
        pass
    
    # ========================================================================
    # 配置管理
    # ========================================================================
    
    def get_config(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        return self.config.get(key, default)
    
    def set_config(self, key: str, value: Any) -> None:
        """设置配置值"""
        self.config[key] = value
    
    def update_config(self, config: Dict[str, Any]) -> None:
        """更新配置"""
        self.config.update(config)
    
    def validate_config(self) -> List[str]:
        """
        验证配置
        
        Returns:
            错误信息列表，空列表表示验证通过
        """
        return []
    
    # ========================================================================
    # 状态管理
    # ========================================================================
    
    def set_state(self, state: PluginState) -> None:
        """设置插件状态"""
        old_state = self.state
        self.state = state
        
        # 触发状态变更回调
        if state == PluginState.LOADED:
            for callback in self._on_load_callbacks:
                callback(self)
        elif state == PluginState.DESTROYED:
            for callback in self._on_unload_callbacks:
                callback(self)
        elif state == PluginState.ERROR:
            for callback in self._on_error_callbacks:
                callback(self)
    
    def is_active(self) -> bool:
        """检查插件是否活跃"""
        return self.state == PluginState.ACTIVE
    
    def is_loaded(self) -> bool:
        """检查插件是否已加载"""
        return self.state in [PluginState.LOADED, PluginState.INITIALIZED, 
                             PluginState.ACTIVE, PluginState.INACTIVE]
    
    # ========================================================================
    # 回调管理
    # ========================================================================
    
    def add_load_callback(self, callback: callable) -> None:
        """添加加载回调"""
        self._on_load_callbacks.append(callback)
    
    def add_unload_callback(self, callback: callable) -> None:
        """添加卸载回调"""
        self._on_unload_callbacks.append(callback)
    
    def add_error_callback(self, callback: callable) -> None:
        """添加错误回调"""
        self._on_error_callbacks.append(callback)
    
    # ========================================================================
    # 工具方法
    # ========================================================================
    
    def log_info(self, message: str) -> None:
        """记录信息日志"""
        if self.logger:
            self.logger.info(f"[{self.name}] {message}")
    
    def log_warning(self, message: str) -> None:
        """记录警告日志"""
        if self.logger:
            self.logger.warning(f"[{self.name}] {message}")
    
    def log_error(self, message: str) -> None:
        """记录错误日志"""
        if self.logger:
            self.logger.error(f"[{self.name}] {message}")
    
    def get_resource_path(self, resource_name: str) -> str:
        """获取插件资源路径"""
        if self.context:
            return self.context.get_resource_path(self.name, resource_name)
        return ""
    
    def get_data_path(self, filename: str) -> str:
        """获取插件数据路径"""
        if self.context:
            return self.context.get_data_path(self.name, filename)
        return ""
    
    # ========================================================================
    # 特殊方法
    # ========================================================================
    
    def __str__(self) -> str:
        return f"{self.name} v{self.version}"
    
    def __repr__(self) -> str:
        return f"Plugin(name='{self.name}', version='{self.version}', state='{self.state.value}')"
    
    def __eq__(self, other) -> bool:
        if not isinstance(other, Plugin):
            return False
        return self.name == other.name and self.version == other.version
    
    def __hash__(self) -> int:
        return hash((self.name, self.version))


class PluginInterface(ABC):
    """
    插件接口抽象基类
    
    定义特定类型插件的接口规范。
    """
    
    @abstractmethod
    def get_interface_version(self) -> str:
        """获取接口版本"""
        pass
    
    @abstractmethod
    def get_supported_operations(self) -> List[str]:
        """获取支持的操作列表"""
        pass


class ProcessorPlugin(Plugin, PluginInterface):
    """
    处理器插件基类
    
    用于视频处理相关的插件。
    """
    
    def get_interface_version(self) -> str:
        return "1.0.0"
    
    def get_supported_operations(self) -> List[str]:
        return ["process"]
    
    @abstractmethod
    async def process(self, input_data: Any, **kwargs) -> Any:
        """处理数据"""
        pass


class ClassifierPlugin(Plugin, PluginInterface):
    """
    分类器插件基类
    
    用于AI分类相关的插件。
    """
    
    def get_interface_version(self) -> str:
        return "1.0.0"
    
    def get_supported_operations(self) -> List[str]:
        return ["classify"]
    
    @abstractmethod
    async def classify(self, input_data: Any, **kwargs) -> Any:
        """分类数据"""
        pass


class OutputPlugin(Plugin, PluginInterface):
    """
    输出插件基类
    
    用于输出相关的插件。
    """
    
    def get_interface_version(self) -> str:
        return "1.0.0"
    
    def get_supported_operations(self) -> List[str]:
        return ["output"]
    
    @abstractmethod
    async def output(self, data: Any, **kwargs) -> Any:
        """输出数据"""
        pass
